package jvm;

/**
 * 理解StringTable
 * @author jack.wu
 * @version 1.0
 * @date 2020-05-19
 */
public class StringTable {

    public static void main(String[] args) {
        StringTable st = new StringTable();
//        st.test2();
        st.test3();
    }


    public void test(){

        String s1 = "Hello";
        String s2 = "String";
        String s3 = "HelloString";
        // 编译器优化
        String s4  = "Hello" + "String";
        // 如果拼接符号的前后出现了变量，则相当于在堆空间中 new String()
        String s5 = s1 + "String";
        String s6 = "Hello" + s2;
        /*
          过程： 1、StringBuilder s = new StringBuilder();
                2、s.append("Hello");
                3、s.append("String");
                4、s.toString();  类似： new String("HelloString")
         */
        String s7 = s1 + s2;
        // 判断字符串常量池中是否存在HelloString值（使用equals方法），如果存在，则返回常量池HelloString的地址
        // 如果不存在，则在常量池中加载一份HelloString，并返回对象的地址
        String s8 = s6.intern();
        System.out.println(s3 == s4); // true
        System.out.println(s3 == s5); // false
        System.out.println(s3 == s6); // false
        System.out.println(s3 == s7); // false
        System.out.println(s5 == s6); // false
        System.out.println(s5 == s7); // false
        System.out.println(s6 == s7); // false
        System.out.println(s3 == s8); // true
    }


    public void test1(){
        // 常量会使用编译器优化
        final String s1 = "a";
        final String s2 = "b";
        String s3 = "ab";
        String s4 = s1 + s2;
        System.out.println(s3 == s4); // true

    }

    public void test2(){
        // 此时会在堆空间和字符串常量池都放入 并返回的时候堆空间的地址
        String s1 = new String("1");
        s1.intern();
        // 只会在字符串常量池中放入，返回的时候字符串常量池中的地址
        String s2 = "1";
        System.out.println(s1 == s2); // false
    }

    public void test3(){
        // 此时会创建6个对象，最后并不会把ab放入字符串常量池中
        String s = new String("a")+ new String("b");
        // 把ab放入常量池
        s.intern();
        String s1 = "ab";
        System.out.println(s == s1);
    }
}
